/**
 * XDevice 配置文件解析实现
 */

#include <xdevice/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* 解析辅助函数 */
static char* trim_whitespace(char* str) {
    char* end;
    while (isspace((unsigned char)*str)) str++;
    if (*str == 0) return str;
    end = str + strlen(str) - 1;
    while (end > str && isspace((unsigned char)*end)) end--;
    end[1] = '\0';
    return str;
}

static int parse_bool(const char* value) {
    if (strcasecmp(value, "true") == 0 || strcasecmp(value, "1") == 0) {
        return 1;
    }
    return 0;
}

static void parse_key_value(char* line, char** key, char** value) {
    char* eq = strchr(line, '=');
    if (!eq) {
        *key = *value = NULL;
        return;
    }
    
    *eq = '\0';
    *key = trim_whitespace(line);
    *value = trim_whitespace(eq + 1);
    
    // 移除引号
    if ((*value)[0] == '"' && (*value)[strlen(*value) - 1] == '"') {
        (*value)[strlen(*value) - 1] = '\0';
        (*value)++;
    }
}

/* 大小解析函数 */
size_t xdevice_config_parse_size(const char* size_str) {
    if (!size_str) return 0;
    
    char* endptr;
    double value = strtod(size_str, &endptr);
    
    if (endptr == size_str) return 0;
    
    // 解析单位
    while (isspace(*endptr)) endptr++;
    
    size_t multiplier = 1;
    if (strcasecmp(endptr, "KB") == 0) {
        multiplier = 1024;
    } else if (strcasecmp(endptr, "MB") == 0) {
        multiplier = 1024 * 1024;
    } else if (strcasecmp(endptr, "GB") == 0) {
        multiplier = 1024 * 1024 * 1024;
    }
    
    return (size_t)(value * multiplier);
}

/* 节点ID转数字 */
int xdevice_config_get_node_id_numeric(const char* node_id) {
    if (!node_id) return -1;
    
    // 如果已经是数字，直接返回
    char* endptr;
    int id = strtol(node_id, &endptr, 10);
    if (*endptr == '\0') {
        return id;
    }
    
    // 从node1, node2等格式提取数字
    if (strncmp(node_id, "node", 4) == 0) {
        return strtol(node_id + 4, NULL, 10) - 1;  // 转为0基索引
    }
    
    // 从cluster_node1等格式提取数字
    if (strncmp(node_id, "cluster_node", 12) == 0) {
        return strtol(node_id + 12, NULL, 10) - 1;  // 转为0基索引
    }
    
    // 尝试从字符串末尾提取数字
    const char* p = node_id + strlen(node_id) - 1;
    while (p >= node_id && *p >= '0' && *p <= '9') {
        p--;
    }
    if (p < node_id + strlen(node_id) - 1) {
        return strtol(p + 1, NULL, 10) - 1;  // 转为0基索引
    }
    
    return 0;  // 默认返回0而不是-1
}

/* 创建默认配置 */
xdevice_config_t* xdevice_config_create_default(void) {
    xdevice_config_t* config = calloc(1, sizeof(xdevice_config_t));
    if (!config) return NULL;
    
    // 设置默认值
    strcpy(config->general.node_id, "node1");
    strcpy(config->general.data_dir, "/tmp/xdevice");
    config->general.log_level = 2; // INFO
    strcpy(config->general.log_file, "/tmp/xdevice.log");
    
    strcpy(config->network.listen_address, "0.0.0.0");
    config->network.listen_port = 8080;
    config->network.connection_timeout = 5000;
    config->network.read_timeout = 10000;
    config->network.write_timeout = 10000;
    config->network.max_connections = 1000;
    
    config->raft.election_timeout_min = 150;
    config->raft.election_timeout_max = 300;
    config->raft.heartbeat_interval = 50;
    config->raft.log_compaction_threshold = 10000;
    config->raft.snapshot_interval = 1000;
    
    strcpy(config->storage.wal_dir, "/tmp/xdevice/wal");
    strcpy(config->storage.wal_file_size, "64MB");
    config->storage.wal_sync_interval = 100;
    config->storage.data_block_size = 4096;
    strcpy(config->storage.cache_size, "128MB");
    config->storage.compression_enabled = true;
    strcpy(config->storage.compression_algorithm, "lz4");
    
    // 多存储后端默认配置
    strcpy(config->storage.local_path, "/tmp/xdevice/data");
    strcpy(config->storage.secondary_path, "/tmp/xdevice/data2");
    strcpy(config->storage.tertiary_path, "/tmp/xdevice/data3");
    
    config->storage.primary_backend = XDEVICE_STORAGE_LOCAL;
    config->storage.secondary_backend = XDEVICE_STORAGE_LOCAL;
    config->storage.tertiary_backend = XDEVICE_STORAGE_LOCAL;
    config->storage.fallback_backend = XDEVICE_STORAGE_MOCK;
    
    config->cluster.node_count = 1;
    config->cluster.default_replica_count = 1;
    config->cluster.failure_detector_interval = 1000;
    config->cluster.failure_detector_timeout = 5000;
    
    config->performance.io_threads = 4;
    config->performance.worker_threads = 8;
    config->performance.batch_size = 1000;
    strcpy(config->performance.max_memory_usage, "2GB");
    config->performance.gc_threshold = 80;
    
    config->security.tls_enabled = false;
    config->security.auth_enabled = false;
    strcpy(config->security.auth_method, "none");
    
    config->loaded = true;
    return config;
}

/* 加载配置文件 */
xdevice_config_t* xdevice_config_load(const char* config_file) {
    if (!config_file) {
        return xdevice_config_create_default();
    }
    
    FILE* file = fopen(config_file, "r");
    if (!file) {
        printf("警告: 无法打开配置文件 %s，使用默认配置\n", config_file);
        return xdevice_config_create_default();
    }
    
    xdevice_config_t* config = xdevice_config_create_default();
    if (!config) {
        fclose(file);
        return NULL;
    }
    
    strncpy(config->config_file, config_file, sizeof(config->config_file) - 1);
    
    char line[1024];
    char current_section[64] = "";
    
    while (fgets(line, sizeof(line), file)) {
        char* trimmed = trim_whitespace(line);
        
        // 跳过空行和注释
        if (*trimmed == '\0' || *trimmed == '#') {
            continue;
        }
        
        // 处理段落标题
        if (*trimmed == '[' && trimmed[strlen(trimmed) - 1] == ']') {
            strncpy(current_section, trimmed + 1, sizeof(current_section) - 1);
            current_section[strlen(current_section) - 1] = '\0';
            continue;
        }
        
        // 解析键值对
        char* key, *value;
        parse_key_value(trimmed, &key, &value);
        if (!key || !value) continue;
        
        // 根据段落处理配置
        if (strcmp(current_section, "general") == 0) {
            if (strcmp(key, "node_id") == 0 || strcmp(key, "process_id") == 0) {
                strncpy(config->general.node_id, value, sizeof(config->general.node_id) - 1);
            } else if (strcmp(key, "data_dir") == 0) {
                strncpy(config->general.data_dir, value, sizeof(config->general.data_dir) - 1);
            } else if (strcmp(key, "log_file") == 0) {
                strncpy(config->general.log_file, value, sizeof(config->general.log_file) - 1);
            }
        } else if (strcmp(current_section, "storage") == 0) {
            if (strcmp(key, "wal_dir") == 0) {
                strncpy(config->storage.wal_dir, value, sizeof(config->storage.wal_dir) - 1);
            } else if (strcmp(key, "local_path") == 0) {
                strncpy(config->storage.local_path, value, sizeof(config->storage.local_path) - 1);
            } else if (strcmp(key, "secondary_path") == 0) {
                strncpy(config->storage.secondary_path, value, sizeof(config->storage.secondary_path) - 1);
            } else if (strcmp(key, "tertiary_path") == 0) {
                strncpy(config->storage.tertiary_path, value, sizeof(config->storage.tertiary_path) - 1);
            } else if (strcmp(key, "nvmf_target") == 0) {
                strncpy(config->storage.nvmf_target, value, sizeof(config->storage.nvmf_target) - 1);
            } else if (strcmp(key, "nfs_mount") == 0) {
                strncpy(config->storage.nfs_mount, value, sizeof(config->storage.nfs_mount) - 1);
            } else if (strcmp(key, "primary_backend") == 0) {
                config->storage.primary_backend = atoi(value);
            } else if (strcmp(key, "secondary_backend") == 0) {
                config->storage.secondary_backend = atoi(value);
            } else if (strcmp(key, "tertiary_backend") == 0) {
                config->storage.tertiary_backend = atoi(value);
            } else if (strcmp(key, "fallback_backend") == 0) {
                config->storage.fallback_backend = atoi(value);
            } else if (strcmp(key, "compression_enabled") == 0) {
                config->storage.compression_enabled = parse_bool(value);
            }
        } else if (strcmp(current_section, "raft") == 0) {
            if (strcmp(key, "election_timeout_min") == 0) {
                config->raft.election_timeout_min = atoi(value);
            } else if (strcmp(key, "election_timeout_max") == 0) {
                config->raft.election_timeout_max = atoi(value);
            } else if (strcmp(key, "heartbeat_interval") == 0) {
                config->raft.heartbeat_interval = atoi(value);
            } else if (strcmp(key, "log_compaction_threshold") == 0) {
                config->raft.log_compaction_threshold = atoi(value);
            } else if (strcmp(key, "snapshot_interval") == 0) {
                config->raft.snapshot_interval = atoi(value);
            }
        } else if (strncmp(current_section, "raft_instance_", 14) == 0) {
            // 解析Raft实例配置，如 [raft_instance_0]
            int instance_id = atoi(current_section + 14);
            if (instance_id >= 0 && instance_id < XDEVICE_MAX_NODES) {
                if (instance_id >= config->raft_instance_count) {
                    config->raft_instance_count = instance_id + 1;
                }
                
                if (strcmp(key, "node_id") == 0) {
                    config->raft_instances[instance_id].node_id = atoi(value);
                } else if (strcmp(key, "data_dir") == 0) {
                    strncpy(config->raft_instances[instance_id].data_dir, value, 
                           sizeof(config->raft_instances[instance_id].data_dir) - 1);
                } else if (strcmp(key, "storage_backend") == 0) {
                    config->raft_instances[instance_id].storage_backend = atoi(value);
                } else if (strcmp(key, "storage_path") == 0) {
                    strncpy(config->raft_instances[instance_id].storage_path, value,
                           sizeof(config->raft_instances[instance_id].storage_path) - 1);
                }
            }
        }
        // 可以继续添加其他段落的解析...
    }
    
    fclose(file);
    return config;
}

/* 验证配置 */
int xdevice_config_validate(const xdevice_config_t* config) {
    if (!config) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    
    // 验证基本配置
    if (strlen(config->general.node_id) == 0) {
        printf("错误: node_id不能为空\n");
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    if (strlen(config->general.data_dir) == 0) {
        printf("错误: data_dir不能为空\n");
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    // 验证Raft配置
    if (config->raft.election_timeout_min >= config->raft.election_timeout_max) {
        printf("错误: election_timeout_min必须小于election_timeout_max\n");
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    if (config->raft.heartbeat_interval >= config->raft.election_timeout_min) {
        printf("错误: heartbeat_interval必须小于election_timeout_min\n");
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    return XDEVICE_CORE_OK;
}

/* 释放配置 */
void xdevice_config_free(xdevice_config_t* config) {
    if (config) {
        free(config);
    }
}
